<?php

namespace App\Libs\Sms;

use App\Exceptions\AppException;
use Illuminate\Support\Facades\Log;

class Sms
{
    const TMPL1 = 2091643; //日喀则-工单生成
    const TMPL2 = 2091646; //日喀则-工单填报
    const TMPL3 = 2091650; //日喀则-工单初审
    const TMPL4 = 2091653; //日喀则-填报超时催单
    const TMPL5 = 2091655; //日喀则-初审超时催单
    const TMPL6 = 1324227; //验证码短信



    public static function sendSms($mobile, $templateId, $params)
    {
        if (!env('IS_SEND_SMS', 0)) {
            return;
        }

        if (!is_array($mobile)) {
            $mobile = explode(',', $mobile);
        }

        $host = env('SEND_SMS_HOST');
        $url = $host . '/api/msg/send/user/define/msg';
        $postData = [
            'mobile' => $mobile,
            'params' => [$params],
            'templateId' => $templateId,
        ];
        $data_string = json_encode($postData);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'X-AjaxPro-Method:ShowList',
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($data_string))
        );
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 超时时间
        $data = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($data, true);
        if (isset($result['success']) && $result['success'] === true) {
            return $result['data'];
        } else {
            Log::error('SMS send error:' . $data);
            return false;
        }
    }

    /**
     * 发送短信验证码
     * @param $phone
     * @return false|int
     */
    public static function sendSmsCode($phone)
    {
        $pattern = '/^1[3456789]\d{9}$/';
        if (!preg_match($pattern, $phone)) {
            throw new AppException('手机号格式不正确');
        }

        $redis = app('redis.connection');
        $codeKey = "sms_code_{$phone}";
        $countKey = "sms_count_{$phone}";
        //1分钟最多发3次
        $count = $redis->get($countKey);
        if (!empty($count) && $count >= 3) {
            throw new AppException('发送消息过于频繁，请稍后再试');
        }

        $code = self::sendSmsByPort($phone);
        if (!$code) {
            throw new AppException('短信发送失败');
        }

        if ($count) {
            $ttl = $redis->ttl($countKey);
            $count++;
            $redis->set($countKey, $count);
            $redis->expire($countKey, $ttl);
        } else {
            $redis->set($countKey, 1);
            $redis->expire($countKey, 60);
        }

        $redis->set($codeKey, $code);
        $redis->expire($codeKey, 60);

        return [];
    }

    /**
     * 发送验证码短信接口
     */
    public static function sendSmsByPort($phone) {
        if (!env('IS_SEND_SMS', 0)) {
            return;
        }
        $host = env('SEND_SMS_HOST');
        $url = $host . '/api/msg/send';
        $postData = [
            'expireMin' => 1,
            'mobile' => $phone,
            'templateId' => self::TMPL6,
        ];
        $data_string = json_encode($postData);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

        curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                'X-AjaxPro-Method:ShowList',
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($data_string))
        );
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5); // 超时时间
        $data = curl_exec($ch);
        curl_close($ch);
        $result = json_decode($data, true);
        if (isset($result['success']) && $result['success'] === true) {
            return $result['data'];
        } else {
            Log::error('SMS send error:' . $data);
            return false;
        }
    }

    /**
     * 检查验证码是否正确
     */
    public static function checkCode($phone, $code)
    {
        $redis = app('redis.connection');
        if (env('APP_DEBUG') && $code == '1234') {
            return true;
        }

        if (!empty($code) && $code != $redis->get("sms_code_{$phone}")) {
            throw new AppException('验证码错误');
        }

        return true;
    }
}
